package com.szw.trading.order.service.impl;

import java.util.Date;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.szw.trading.order.jedis.MarketOrderPub;
import com.szw.trading.order.service.BaseService;
import com.szw.trading.order.service.OrderService;
import com.szw.trading.persistence.entity.Customer;
import com.szw.trading.persistence.entity.CustomerTradingAccount;
import com.szw.trading.persistence.entity.Login;
import com.szw.trading.persistence.entity.Order;
import com.szw.trading.persistence.repository.CustomerRepository;
import com.szw.trading.persistence.repository.CustomerTradingAccountRepository;
import com.szw.trading.persistence.repository.LoginRepository;
import com.szw.trading.persistence.repository.OrderRepository;
import com.szw.trading.web.bean.CancelOrderRequest;
import com.szw.trading.web.bean.CreateOrderRequest;
import com.szw.trading.web.bean.Response;
import com.szw.trading.web.constants.Offsetted;
import com.szw.trading.web.constants.OrderQueueName;
import com.szw.trading.web.constants.OrderSide;
import com.szw.trading.web.constants.OrderStatus;
import com.szw.trading.web.constants.OrderType;
import com.szw.util.OrderNoGenerator;
import com.szw.util.RedisCacheUtil;


@Service
public class OrderServiceImpl extends BaseService implements OrderService {

	@Autowired
	private LoginRepository loginRepository;
	@Autowired
	private CustomerRepository customerRepository;
	@Autowired
	private CustomerTradingAccountRepository customerTradingAccountRepository;
	@Autowired
	private RedisCacheUtil<Order> redisCacheUtil;
	@Autowired
	private OrderNoGenerator orderNoGenerator;
	@Autowired
	private OrderRepository orderRepository;
	@Value("${getMarketDataByCode.url}")
	private String getMarketDataByCodeUrl;
	@Autowired
	private MarketOrderPub marketOrderPub;

	@Override
	@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)
	public Response createOrder(CreateOrderRequest request) {

		Login login = loginRepository.findByLoginId(Integer.valueOf(request.getLoginId()));
		Customer customer = customerRepository.findByCustomerId(login.getCustomerId());
		CustomerTradingAccount cta = customerTradingAccountRepository.findByCustomerId(customer.getCustomerId());

		// 卖出订单要看原订单状态是否符合下单要求
		if (OrderSide.SELL == request.getOrderSide()) {
			Order originOrder = orderRepository.findByOrderNoAndTradingAccountIdAndStatus(request.getOffsetOrderNo(), cta.getTradingAccountId(),
					OrderStatus.SUCCESS);
			if (null == originOrder) {
				return Response.FAILUE("订单状态不允许卖出");
			}
		}

		Order order = new Order();
		order.setOrderNo(orderNoGenerator.getOrderNo("ST", login.getLoginName()));
		order.setCreateTime(new Date());
		order.setUpdateTime(new Date());
		order.setTradingAccountId(cta.getTradingAccountId());
		order.setOffsetted(Offsetted.NO_OFFSETTED);
		BeanUtils.copyProperties(request, order);
		order.setStatus(OrderStatus.PENDING);

		Order rtnOrder = orderRepository.save(order);

		if (OrderType.MARKET_ORDER == order.getOrderType()) {
			// redisCacheUtil.pushCacheList(OrderQueueName.MARKET_ORDER_QUEUE.name(), rtnOrder);
			log.info("【创建订单】判断为市价单，将发布市价单消息...");
			marketOrderPub.marketOrderPub(OrderQueueName.MARKET_ORDER_QUEUE.name(), JSON.toJSONString(rtnOrder));
		} else if (OrderType.LIMIT_ORDER == order.getOrderType()) {
			redisCacheUtil.pushCacheList(genLimitOrderQueueName(rtnOrder), rtnOrder);
		}

		return Response.SUCCESS(order);
	}

	public String genLimitOrderQueueName(Order order) {
		return OrderQueueName.LIMIT_ORDER_QUEUE.name() + ":" + order.getStockCode() + "-" + order.getOrderPrice();
	}

	@Override
	public Response cancelOrder(CancelOrderRequest request) {
		Login login = loginRepository.findByLoginId(Integer.valueOf(request.getLoginId()));
		CustomerTradingAccount cta = customerTradingAccountRepository.findByCustomerId(login.getCustomerId());
		Order order = orderRepository.findByOrderNoAndTradingAccountId(request.getCancelOrderNo(), cta.getTradingAccountId());

		if (null == order) {
			return Response.FAILUE("订单不存在");
		}
		if (OrderStatus.PENDING != order.getStatus() && OrderStatus.WAITING != order.getStatus()) {
			return Response.FAILUE("订单状态不允许取消");
		}

		order.setStatus(OrderStatus.CANCELED);
		order.setUpdateTime(new Date());
		Order rtnOrder = orderRepository.save(order);

		return Response.SUCCESS(rtnOrder);
	}

}
